import { ThreeBase } from "../js/ThreeBase";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import {
    AmbientLight, Box3, DirectionalLight,
    LinearFilter, RGBAFormat, Vector2,
    Mesh, PCFSoftShadowMap, Spherical, Vector3, WebGLMultisampleRenderTarget, WebGLRenderTarget, Group
} from "three";
import { TWEEN } from "../js/TWEEN";
import { PixelOutlinePass } from '../js/PixelOutlinePass'
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass";
import { WEBGL } from "three/examples/jsm/WebGL";
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer';

//  我的代码
import { getAllChannels }   from  '@/api/demo.js'

export class View extends ThreeBase {
    constructor(dom, $) {
        super(dom);
        this.$ = $;
        this.setComposer();
        this.initModel();
        this.initLight();
    }

    setComposer() {
        this.renderer.autoClear = true;
        const ratio = window.devicePixelRatio;
        const w = this.width * ratio,
            h = this.height * ratio;
        let renderTargetParameters = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat, stencilBuffer: true };
        let renderTarget = new WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters);
        if (WEBGL.isWebGL2Available()) {
            const size = this.renderer.getDrawingBufferSize(new Vector2());
            renderTarget = new WebGLMultisampleRenderTarget(size.width, size.height, {
                format: RGBAFormat,
                magFilter: LinearFilter,
                minFilter: LinearFilter
            });
        }

        this.composer = new EffectComposer(this.renderer, renderTarget);
        this.composer.setSize(w, h);
        this.composer.setPixelRatio(window.devicePixelRatio);
        this.renderScene = new RenderPass(this.scene, this.camera);
        this.composer.addPass(this.renderScene);
        this.pix = new PixelOutlinePass(this.camera);
        this.pix.thickness = 1.5;
        this.composer.addPass(this.pix);
    }


    resize = () => {
        this.initWidthAndHeight();
        this.camera.aspect = this.width / this.height;
        this.camera.updateProjectionMatrix();
        this.composer.setSize(this.width, this.height);
        this.pix.setSize(this.width, this.height);
        this.renderer.setSize(this.width, this.height);
        this.css2DRenderer.setSize(this.width, this.height);
    }

    render = () => {
        this.css2DRenderer.render(this.scene, this.camera);
        this.composer.render();
        TWEEN.update();
        this.eventList.runAll();
        this.controls.update();
    }

     initClick(model) {
        //  在这里加上 async  
        document.body.addEventListener('click', async e => {
            const raycasters = this.getRaycastersByObject(e, this.stations);
            if (raycasters.length > 0) {
                const { object, point } = raycasters[0];
                // console.log(point)
                if (object.name == 'AM218_029_CCTV') {
                    this.$.show = true;
                } else {
                    let station = object.parent.parent;
                    let isOn = station.isOn;

                    //  自己的代码
                    console.log(await getAllChannels());
                    // const { data:res } =  getAllChannels()  // 测试 后端返回的数据
                    // console.log(res.data.channels,'999000');

                    station.traverse(  (m) => {
                        if (m instanceof Mesh) {
                            if (m.material.name == '02 - Default') {
                                if (!isOn) {
                                    

                                    var colors = 0x008000  // 在请求文件 拿到后端返回的颜色, 然后再把颜色 保存到这里
                                    // m.material.color.set(0x00ffff);
                                    m.material.color.set(colors); // 点击后的工位颜色
                                } else {
                                    // m.material.color.setRGB(1,0.23,.0);
                                    m.material.color.setRGB(0, 0, 205); // 这是什么颜色
                                }
                            }
                        }
                    });
                    station.isOn = !isOn;
                }

            }
        },true);

        this.container.addEventListener('mousemove', e => {
            const raycasters = this.getRaycastersByObject(e, this.stations);
            this.pix.clearOutlines();
            if (raycasters.length > 0) {
                const { object } = raycasters[0];
                let meshes = [];
                if (object.name != 'AM218_029_CCTV') {
                    let station = object.parent.parent;
                    station.traverse(m => {
                        if (m instanceof Mesh) {
                            meshes.push(m);
                        }
                    });
                } else {
                    meshes = [object];
                }
                //   鼠标在指定元素身上移动
                // this.pix.setOutline(0x00ffff,meshes);
                this.pix.setOutline(0x800080, meshes);
            }
        });
    }

    async initModel() {
        //  这个是调整 模型位置
        this.scene.position.y = 10;
        // this.scene.position.z = 6;

        this.scene.background = this.loadTexture('/bg.jpg');
        // let { envMap } = await this.getCubeMapTexture('venice_sunset_1k.jpg');
        let { envMap } = await this.getCubeMapTexture('footprint_court_2k.pic');
        this.envMap = envMap;

        let group = new Group();

        let xj = await this.loadGLTFModel('/cctv.glb');
        let model = xj.scene.getObjectByName('AM218_029_CCTV');
        this.stations = [model];
        model.scale.multiplyScalar(30);
        model.position.copy(new Vector3(1.322954849743868, 1.4432977888131073, -0.6007013202311218));
        model.rotation.y += Math.PI / 2;
        this.scene.add(model);

        let { scene } = await this.loadGLTFModel('/bangongshi.glb');
        let glass = ['Box076', 'Object'];

        scene.traverse(m => {
            if (m instanceof Mesh) {
                if (glass.includes(m.name)) {
                    m.material.transparent = true;
                    m.material.opacity = .2;
                    m.material.side = 0;
                } else if (m.name == 'dimian') {
                    m.receiveShadow = true;
                } else {
                    m.castShadow = true;
                }
                if (m.name == 'waiqiang') {
                    m.material.envMap = this.envMap;
                    m.material.metalness = .5;
                    m.material.roughness = .5;
                    m.material.color.set(0xF8F8FF);
                }
                if (m.material.name == '02 - Default') {
                    m.material = m.material.clone();
                }
            }
            if (m.name.indexOf('station') >= 0 && m.type == 'Object3D' && m.children.length == 2) {
                this.stations.push(m);
            }
        });

        ['温度', '湿度', 'PM2.5', '漏水'].forEach((m, i) => {
            let span = document.createElement('span');
            Object.assign(span.style, {
                color: 'white',
                borderRadius: '2px',
                border: '1px solid white',
                fontSize: '12px',
                background: 'rgba(0,0,0,.5)',
                padding: '2px'
            });
            let a = new CSS2DObject(span);
            if (m == '温度') {
                a.position.copy(new Vector3(-9.335691481134141, 1.5563, -1.1817732107496786));
                setInterval(() => {
                    span.innerHTML = m + ': ' + (Math.random() * 30).toFixed(2) + "℃"
                }, 1000);
            } else if (m == '湿度') {
                a.position.copy(new Vector3(-0.7213252032682609, 1.5563366455123553, -0.6007013224769695));
                setInterval(() => {
                    span.innerHTML = m + ': ' + (Math.random() * 100).toFixed(2);
                }, 1000);
            } else if (m == "PM2.5") {
                a.position.copy(new Vector3(14.231507538820805, 1.1660371702225039, -0.5742441327608175));
                setInterval(() => {
                    span.innerHTML = m + ': ' + (Math.random() * 100).toFixed(2);
                }, 1000);
            } else {
                a.position.copy(new Vector3(0.40500864625263155, 1.513518904016674, -9.575183926546943));
                setInterval(() => {
                    span.innerHTML = m + ': 无';
                }, 1000);
            }

            this.scene.add(a);
            group.add(scene);
        });



        this.setControls(group);

        this.scene.add(group);


        this.renderer.setAnimationLoop(this.render.bind(this));
        window.addEventListener('resize', this.resize.bind(this));

        this.initClick(group);
    }


    setControls(model) {
        const { camera } = this;
        let box3 = new Box3().setFromObject(model);
        let center = box3.getCenter(new Vector3());
        model.position.add(model.position.clone().sub(center));
        camera.position.copy(new Vector3().setFromSpherical(
            new Spherical(box3.getSize(new Vector3()).length(), Math.PI / 4, 0)).clone());
        camera.lookAt(center);

        const controls = new OrbitControls(camera, this.container);
        controls.minPolarAngle = 0;
        controls.maxPolarAngle = Math.PI / 2;
        controls.zoomSpeed = 2.0;
        controls.maxDistance = 2000;
        this.controls = controls;
        this.controls.update();
    }

    initLight() {
        this.renderer.shadowMap.enabled = true;
        this.renderer.shadowMap.type = PCFSoftShadowMap;
        this.scene.add(new AmbientLight(0xffffff, .5));
        let dir = new DirectionalLight(0xffffff, .4);
        dir.castShadow = true;
        const size = 80;
        dir.shadow.camera.top = size;
        dir.shadow.camera.bottom = -size;
        dir.shadow.camera.left = -size;
        dir.shadow.camera.right = size;
        dir.shadow.mapSize.x = 1024;
        dir.shadow.mapSize.y = 1024;
        dir.position.set(-size, size, size);
        this.scene.add(dir);
    }
}